package com.hb.trade.server.project.order.controller;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.enums.FeeTypeEnum;
import com.hb.core.pojo.parent.MPBaseController;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.order.dto.UserOrderDTO;
import com.hb.core.pojo.project.order.dto.UserOrderGoodsDTO;
import com.hb.core.pojo.project.order.entity.Invoice;
import com.hb.core.pojo.project.order.entity.UserOrder;
import com.hb.core.pojo.project.order.entity.UserOrderGoods;
import com.hb.core.pojo.project.order.vo.UserOrderExportListVO;
import com.hb.core.pojo.project.order.vo.UserOrderListVO;
import com.hb.core.pojo.project.proj.entity.AbstractProject;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.entity.BidSection;
import com.hb.trade.server.project.file.service.BidBuyRecordService;
import com.hb.trade.server.project.order.manager.UserOrderManager;
import com.hb.trade.server.project.order.service.InvoiceService;
import com.hb.trade.server.project.order.service.UserOrderGoodsService;
import com.hb.trade.server.project.order.service.UserOrderService;
import com.hb.trade.server.project.proj.service.ProjectService;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import org.fzzn.core.model.enums.AuditStatusEnum;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.util.Enums;
import org.fzzn.core.util.MsgUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单信息 前端控制器
 * </p>
 *
 * @author zhaojk
 * @since 2021-08-30
 */
@RestController
public class UserOrderController extends MPBaseController<UserOrder, UserOrderService> {

    protected final ProjectService projectService;
    protected final BidSectionService bidSectionService;
    protected final UserOrderGoodsService userOrderGoodsService;
    protected final BidBuyRecordService bidBuyRecordService;
    protected final InvoiceService invoiceService;


    public UserOrderController(UserOrderService userOrderService, ProjectService projectService, BidSectionService bidSectionService, UserOrderGoodsService userOrderGoodsService, BidBuyRecordService bidBuyRecordService, InvoiceService invoiceService) {
        super(userOrderService);
        this.projectService = projectService;
        this.bidSectionService = bidSectionService;
        this.userOrderGoodsService = userOrderGoodsService;
        this.bidBuyRecordService = bidBuyRecordService;
        this.invoiceService = invoiceService;
    }

    /**
     * @param userOrder:
     * @Description: 投标人分页查询购买文件列表
     * @Author: zhongdl
     * @Date:2021/12/22 11:39
     * @return: {@link PageResult<   UserOrderDTO  > }
     **/
    @PostMapping("/userOrder/pagePurchaseFile")
    public Message<PageResult<UserOrderDTO>> findPurchaseFileList(@RequestBody UserOrderDTO userOrder) {
        PageResult<UserOrderDTO> page = service.pagePurchaseFile(userOrder);
        return MsgUtil.success(page);
    }

    /**
     * @param userOrder:
     * @Description: 投标人扫静态付款码购买文件
     * @Author: zhongdl
     * @update zhaojk
     * @Date:2021/12/22 16:39
     * @return: {@link Message< UserOrderGoodsDTO> }
     **/
    @PostMapping("/userOrder/purchaseFile")
    @Transactional(rollbackFor = Exception.class)
    public Message<?> purchaseFile(@RequestBody UserOrderDTO userOrder) {
        userOrder.buildBaseData(1);
        UserOrderManager orderManager = userOrder.to(UserOrderManager.class);
        orderManager.init();
        // 保存订单
        service.saveOrUpdate(orderManager);

        List<UserOrderGoods> goods = orderManager.getGoods();
        //保存订单商品表
        boolean batch = userOrderGoodsService.saveBatch(goods);
        return MsgUtil.success(orderManager);
    }

    /**
     * @param goodsDTO:
     * @Description: 获取指定费用类型的收费情况
     * @Author: zhongdl
     * @Date:2022/2/21 18:58
     * @return: {@link Message< UserOrderGoodsDTO> }
     **/
    @PostMapping("/userOrder/feeInfo")
    public Message<?> feeInfo(@RequestBody UserOrderGoodsDTO goodsDTO) {
        JSONObject root = JSONUtil.createObj();

        Long sectionId = goodsDTO.getSectionId();
        AbstractProject project = projectService.getProjectBySectionId(sectionId);
        BidSection section = bidSectionService.getById(sectionId);

        // 查询该标段下的费用信息
        FeeTypeEnum feeTypeEnum = Enums.of(FeeTypeEnum.class, goodsDTO.getFeeType());
        JSONObject priceInfo = service.getPriceInfo(sectionId, feeTypeEnum);

        JSONObject orderInfo = JSONUtil.createObj();
        orderInfo.putOpt("saleUnit", project.getAgencyOrganizeInfo());
        orderInfo.putOpt("projectName", project.getProjectName());
        orderInfo.putOpt("sectionCode", section.getSectionCode());
        orderInfo.putOpt("sectionName", section.getSectionName());
        orderInfo.putAll(priceInfo);

        // 用户的付款凭证信息
        UserOrderGoodsDTO userOrderGoodsDTO = userOrderGoodsService.getUserOrderGoodsDTO(goodsDTO.getFeeType(), sectionId, goodsDTO.getOrgId());

        if (userOrderGoodsDTO != null) {
            //查询订单信息
            UserOrder userOrder = service.getById(userOrderGoodsDTO.getOrderId());
            if (userOrder != null) {
                userOrderGoodsDTO.setUserOrderDTO(userOrder.to(UserOrderDTO.class));
                //查询发票的开具状态
                Invoice invoice = invoiceService.getInvoiceByOrderId(userOrderGoodsDTO.getOrderId());
                if (invoice != null){
                    //发票是否开具成功
                    userOrderGoodsDTO.setInvoiceSuccessFlag(invoice.getInvoiceSuccessFlag());

                }
                root.putOpt("userOrderInfo", userOrderGoodsDTO);
            }
        }

        root.putOpt("orderInfo", orderInfo);
        return MsgUtil.success(root);
    }

    /**
     * 第三方支付创建订单
     *
     * @param userOrder
     * @return
     */
    @PostMapping("/userOrder/createOrder")
    public Message<UserOrderDTO> createOrder(@RequestBody UserOrderDTO userOrder) {
        userOrder.buildBaseData(1);
        UserOrderManager orderManager = userOrder.to(UserOrderManager.class);
        orderManager.init();

        List<UserOrderGoods> goods = orderManager.getGoods();

        // 保存订单
        service.saveOrUpdate(orderManager);
        //保存订单商品表
        boolean batch = userOrderGoodsService.saveBatch(goods);
        return MsgUtil.success(orderManager);
    }

    @PostMapping("/userOrder/feeManagers")
    public Message<?> feeManagers(@RequestBody BidSectionDTO section) {
        Long sectionId = section.getId();
        Page<UserOrderDTO> pages = section.pages();
        service.feeManagers(pages, sectionId, section.getFeeType());
        PageResult<UserOrderDTO> result = PageResult.get(pages);
        return MsgUtil.success(result);
    }

    /**
     * 修改订单状态
     * ID为空时根据订单号查询
     *
     * @param orderDTO
     * @return
     */
    @PostMapping("/userOrder/updateOrderStatus")
    public Message<UserOrderDTO> updateOrderStatus(@RequestBody UserOrderDTO orderDTO) {
        UserOrder rawUserOrder = service.getUserOrder(orderDTO);
        if (rawUserOrder == null) {
            return MsgUtil.fail("订单信息不存在");
        }
        orderDTO.to(rawUserOrder);
        rawUserOrder.buildBaseData(2);
        boolean update = service.updateById(rawUserOrder);

        if (!update) {
            return MsgUtil.msg(MsgEnum.FAILURE);
        }

        // 将更新之后的数据返回
        UserOrderDTO userOrder = service.getWholeInfo(orderDTO.getId());
        return MsgUtil.success(userOrder);
    }

    /**
     * 费用管理统计列表
     *
     * @param sectionDTO
     * @return
     */
    @PostMapping("/userOrder/fee/statistics")
    public Message<?> feeStatistics(@RequestBody BidSectionDTO sectionDTO) {
        PageResult<UserOrderDTO> orders = service.feeStatistics(sectionDTO);
        return MsgUtil.success(orders);
    }

    /**
     * 查询订单详情
     * 带着商品列表信息
     *
     * @param orderDTO
     * @return
     */
    @PostMapping("/userOrder/orderDetail")
    public Message<UserOrderDTO> orderDetail(@RequestBody UserOrderDTO orderDTO) {
        Long orderDTOId = orderDTO.getId();
        UserOrderDTO userOrder = service.getWholeInfo(orderDTOId);
        return MsgUtil.success(userOrder);
    }

    @PostMapping("/userOrder/pageRecord")
    public Message<?> pageRecord(@RequestBody UserOrderGoodsDTO goodsDTO) {
        PageResult<UserOrderDTO> list = service.pageWithGoodInfo(goodsDTO);
        return MsgUtil.success(list);
    }

    /**
     * 递交投标保证金和履约保证金
     *
     * @param order
     * @return
     */
    @PostMapping("/userOrder/saveBondInfo")
    public Message<?> saveBondInfo(@RequestBody UserOrderDTO order) {
        // 查询价格
        UserOrderManager userOrderManager = order.to(UserOrderManager.class);
        userOrderManager.buildBaseData(1);
        userOrderManager.init();

        boolean save = service.saveOrUpdate(userOrderManager);
        List<UserOrderGoods> goods = userOrderManager.getGoods();
        boolean batch;
        if (null != order.getId()) {
            batch = userOrderGoodsService.updateBatchById(goods);
        } else {
            batch = userOrderGoodsService.saveBatch(goods);
        }
        return MsgUtil.success(save && batch);
    }

    /**
     * 获取指定标段下的费用
     *
     * @param sectionId 标段ID
     * @param feeType   费用类型
     * @return
     */
    @PostMapping("/userOrder/getPrice")
    public Message<BigDecimal> getPrice(@RequestParam Long sectionId, @RequestParam Integer feeType) {
        BigDecimal price = service.getPrice(sectionId, feeType);
        return MsgUtil.success(price);
    }

    /**
     * 查询指定投标人企业下的费用缴纳状态
     *
     * @param userOrderGoodsDTO#sectionId                标段ID
     * @param userOrderGoodsDTO#feeType                  费用类型
     * @param userOrderGoodsDTO#userOrderDTO#orderStatus 订单状态
     * @return
     */
    @PostMapping("/userOrder/queryUserOrder")
    public Message<UserOrder> queryUserOrder(@RequestBody UserOrderGoodsDTO userOrderGoodsDTO) {
        UserOrder userOrder = service.queryUserOrder(userOrderGoodsDTO);
        return MsgUtil.success(userOrder);
    }

    /**
     * 查询指定投标人企业下的费用缴纳状态
     *
     * @return
     */
    @PostMapping("/userOrder/getOrder")
    public Message<UserOrder> getOrder(String primaryKey) {
        QueryWrapper<UserOrder> wrapper = UserOrderDTO.wrapper();
        wrapper.eq("out_order_no", primaryKey).or((w) -> w.eq("id", primaryKey)).last("limit 1");
        UserOrder one = service.getOne(wrapper);
        if (one == null) {
            return MsgUtil.fail("[primaryKey: " + primaryKey + "]订单信息不存在");
        }
        return MsgUtil.success(one);
    }

    /**
     *
     * @Description: 根据费用类型查询订单列表
     * @Author: zhongdl
     * @Date:2022/3/1 13:27
     * @param goodsDTO:
     * @return: {@link Message< List< UserOrderDTO>> }
     **/
    @PostMapping("/userOrder/listUserOrderByFreeType")
    Message<List<UserOrderDTO>> listUserOrderByFreeType(@RequestBody UserOrderGoodsDTO goodsDTO) {
        List<UserOrderDTO> list = service.listUserOrderByFreeType(goodsDTO.getSectionId(), goodsDTO.getFeeType(), goodsDTO.getOrgId());

        return MsgUtil.success(list);
    }

    /**
     * 已支付订单分页列表
     *
     * @author yuezheng
     * @param userOrderDTO
     * @return Message<PageResult < UserOrderListVO>>
     * @date 2022/4/13 11:37 PM
     */
    @PostMapping("/userOrder/listSuccess")
    Message<PageResult<UserOrderListVO>> listSuccessUserOrder(@RequestBody UserOrderDTO userOrderDTO) {
        PageResult<UserOrderListVO> result = service.selectOrderSuccessList(userOrderDTO);
        List<UserOrderListVO> collect = result.getRecords().stream().map(item -> {
            item.setSource("赢标平台");
            return item;
        }).collect(Collectors.toList());
        result.setRecords(collect);
        return MsgUtil.success(result);
    }

    /**
     * 统计本月成交额
     *
     * @author yuezheng
     * @param
     * @return java.math.BigDecimal
     * @date 2022/4/14 10:07 AM
     */
    @PostMapping("/userOrder/count/amount")
    Message<BigDecimal> selectOrderAmountCountToMonth(@RequestBody UserOrderDTO userOrderDTO) {
        return MsgUtil.success(service.countByOrderAmountToMonth(userOrderDTO));
    }

    /**
     * 统计本月成数
     *
     * @author yuezheng
     * @param
     * @return java.math.BigDecimal
     * @date 2022/4/14 10:07 AM
     */
    @PostMapping("/userOrder/count")
    Message<Integer> selectOrderCountToMonth(@RequestBody UserOrderDTO userOrderDTO) {
        return MsgUtil.success(service.countOrderByToMonth(userOrderDTO));
    }

    /**
     * 查询导出数据
     *
     * @author yuezheng
     * @param userOrderDTO
     * @return org.fzzn.core.model.msg.Message
     * @date 2022/4/14 4:22 PM
     */
    @PostMapping("/userOrder/export")
    Message<List<UserOrderExportListVO>> selectExportExcelList(@RequestBody UserOrderDTO userOrderDTO) {
        List<UserOrderExportListVO> orderExportList = this.service.exportExcelList(userOrderDTO);

        Set<Long> orgSet = orderExportList.stream().map(UserOrderExportListVO::getProjectOrgId).collect(Collectors.toSet());
        if (orgSet.size() > 1) {
            return MsgUtil.fail("org");
        }

        Set<Long> projectSet = orderExportList.stream().map(UserOrderExportListVO::getProjectId).collect(Collectors.toSet());
        if (projectSet.size() > 13) {
            return MsgUtil.fail("pro");
        }

        return MsgUtil.success(orderExportList);
    }

    @PostMapping("/userOrder/OrderPayStatus")
    public Message<Boolean> OrderPayStatus(@RequestBody UserOrderDTO userOrderDTO){
        UserOrderGoods userOrderGoods = userOrderGoodsService.getUserOrderGoodsDTO(userOrderDTO.getFeeType(), userOrderDTO.getSectionId(), userOrderDTO.getOrgId());
        if (userOrderGoods == null){
            return MsgUtil.msg(false);
        }
        UserOrder userOrder = service.getById(userOrderGoods.getOrderId());
        if (userOrder!=null && userOrder.getAuditStatus().equals(AuditStatusEnum.PASSED.getCode())){
            return MsgUtil.msg(true);
        }

        return MsgUtil.msg(false);

    }
}
